<?php
/**
 * 简单余弦相似度算法
 */

class SampleCosineSimilarity
{
    /**
     * 获得向量的模
     * @param array $arrParam 传入分析数据的基准点的N维向量。|eg:array(1,1,1,1,1);
     * @return float $strMod
     */
    private static function getMarkMod($arrParam) {
        $strModDouble = 0;
        foreach ($arrParam as $val) {
            $strModDouble += $val * $val;
        }
        $strMod = sqrt($strModDouble);
        //是否需要保留小数点后几位
        return $strMod;
    }

    /**
     * 余弦相似度算法
     * @param array $arrMark 标杆向量数组
     * @param array $arrAnaly 分析向量数组
     * @return float $strCosine     余弦值[-1, 1]
     */
    public static function getCosine($arrMark, $arrAnaly) {
        $strVector = 0;
        $strCosine = 0;
        $intLenth = count($arrMark);
        for ($i = 0; $i < $intLenth; $i++) {
            $strMarkVal = $arrMark[$i];
            $strAnalyVal = $arrAnaly[$i];
            $strVector += $strMarkVal * $strAnalyVal;
        }
        $strMarkMod = self::getMarkMod($arrMark); // 求标杆向量的模
        $arrAnalyMod = self::getMarkMod($arrAnaly); //求分析向量的模
        $strFenzi = $strVector;
        $strFenMu = $arrAnalyMod * $strMarkMod;
        if (0 !== (int) $strFenMu) {
            $strCosine = $strFenzi / $strFenMu;
        }
        return $strCosine;
    }
}